package net.oschina.git.hikoyan.helloapi.processor.asyncservlet;

import net.oschina.git.hikoyan.helloapi.async.flowcontrol.FlowControlMap;
import net.oschina.git.hikoyan.helloapi.common.request.BaseParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * Created by yan on 17/2/22.
 */
public class AsyncTask implements Runnable {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    private DeferredResult<String> deferredResult;
    private BaseParam parameter;

    public AsyncTask(DeferredResult<String> deferredResult, BaseParam parameter) {
        this.deferredResult = deferredResult;
        this.parameter = parameter;
    }

    public void run() {
        Semaphore semaphore = FlowControlMap.getCctDataMap().get(parameter.getAppId());
        if (semaphore != null) {//并发模式
            boolean cctResult = false;
            try {
                try {
                    cctResult = semaphore.tryAcquire(100L, TimeUnit.MILLISECONDS);
                    logger.info("cctResult : ", String.valueOf(cctResult));
                } catch (InterruptedException e1) {
                    logger.error("并发异常");
                    deferredResult.setResult("并发异常");
                    return;
                }

                if (cctResult) {//允许访问
                    doTask();
                } else {
                    deferredResult.setResult("并发流量溢出");
                }
            } finally {
                if (cctResult) {//如果获取成功,则必须释放
                    semaphore.release();
                }
            }
        } else {
            doTask();
        }
    }

    public void doTask() {
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info("makeRemoteCall 调用！thread id is : " + Thread.currentThread().getId());
        logger.info(parameter.getAppId());
        deferredResult.setResult(parameter.getAppId());
        logger.info("makeAsyncTask end");
    }
}
